﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using PureMVC.Interfaces;
using PureMVC.Patterns;
using SMS.Core.Model;
using SMS.Core.View.Component;
using SMS.Core.Controller.Commands;

namespace SMS.Core.View
{
    public class LoginMediator : Mediator, IMediator
    {
        #region Constants

        // Cannonical name of the Mediator
        public new const string NAME = "LoginMediator";

        #endregion

        #region Constructors

        // Constructor
        public LoginMediator(UserControl viewComponent)
            : base(NAME, viewComponent)
        {
            LoginPanel component = (LoginPanel)viewComponent;
            m_viewComponent = component;

            // Set control behavior
            foreach (TextBox textBox in component.Controls.OfType<TextBox>())
            {
                textBox.TextChanged += new EventHandler(ConnFields_TextChanged);
            }
            component.LoginButton.Click += new EventHandler(LoginButton_Click);
            component.DisconnectButton.Click += new EventHandler(DisconnectButton_Click);
            
            // Set AcceptButton to Log In and CancelButton to null
            component.ParentForm.AcceptButton = component.LoginButton;
            component.ParentForm.CancelButton = null;
        }
        
        #endregion  

        #region Public Methods

        public override IList<string> ListNotificationInterests()
        {
            return new List<string>() 
            {
                ModelConstants.UserAccount.LOGIN_FAILURE,
                ModelConstants.UserAccount.LOGIN_SUCCESS
            };
        }

        public override void HandleNotification(INotification notification)
        {
            switch (notification.Name)
            {
                case ApplicationConstants.STARTUP_SUCCESS:
                    //(m_viewComponent as LoginForm).ShowStartupSuccessDialog();
                    break;
                case ModelConstants.UserAccount.LOGIN_SUCCESS:
                    MessageBox.Show(String.Format("Hello, {0} {1}.", 
                        notification.Body.ToString(),
                        "you piece of shit"));
                    break;
            }
        }

        public override void OnRegister()
        {
            Facade.RegisterCommand(ModelConstants.UserAccount.LOGIN, typeof(LoginCommand));
            Facade.RegisterCommand(ModelConstants.UserAccount.LOGIN_SUCCESS, typeof(MainStartupCommand));
        }

        public override void OnRemove()
        {
            Facade.RemoveCommand(ModelConstants.UserAccount.LOGIN);
            Facade.RemoveCommand(ModelConstants.UserAccount.LOGIN_SUCCESS);
        }

        #endregion

        #region Private & Internal Methods

        #region Event Handlers

        private void ConnFields_TextChanged(object sender, EventArgs e)
        {
            LoginPanel component = (LoginPanel)ViewComponent;

            var connFields = (ViewComponent as UserControl).Controls.OfType<TextBox>();

            if (connFields.ToList()[0].Text != "" && 
                connFields.ToList()[0].Text != null &&
                connFields.ToList()[1].Text != "" && 
                connFields.ToList()[1].Text != null)
            {
                component.LoginButton.Enabled = true;
            }
            else
            {
                component.LoginButton.Enabled = false;
            }
        }

        void LoginButton_Click(object sender, EventArgs e)
        {
            var component = (LoginPanel)ViewComponent;
            List<string> connSettings = new List<string>
            {
                component.UsernameField.Text,
                component.PasswordField.Text
            };

            try
            {
                SendNotification(ModelConstants.UserAccount.LOGIN, connSettings);
            }
            catch (TargetInvocationException tie)
            {
                SendNotification(ModelConstants.UserAccount.LOGIN_FAILURE, connSettings);
                MessageBox.Show(((LoginException)tie.InnerException).Message, 
                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void DisconnectButton_Click(object sender, EventArgs e)
        {
            // Restart the application.
            (ViewComponent as UserControl).ParentForm.Dispose();
            // Attempt disconnecting from the database.
            SendNotification(ModelConstants.Connection.DISCONNECT);
            Facade.RemoveMediator(StartupMediator.NAME);
            ApplicationFacade.Instance.Startup(new LoginForm());
        }

        private void ViewComponent_Load(object sender, EventArgs e)
        {
            SendNotification(ApplicationConstants.STARTUP_SUCCESS,
                (ViewComponent as LoginForm).CustomComponent);
        }

        #endregion

        #endregion
    }
}